package com.productAndConsume;

import java.util.Date;

/**
 *  生产者与消费者同步问题
 *  synchronized
 *  加锁的方法中，执行的思路是 判断等待 + 业务 +通知
 * */
public class TestSynchronized {
    /**
     *  两个线程 A 、B，同时操作一个变量
     *
     *  测试 一对生产者消费者不会出问题 多对消费者生产出问题
     *  synchronized锁 。。。有问题 等待唤醒，通知唤醒 有产品时 2个消费者一直在等待唤醒。
     * */

    public static void main(String[] args) throws InterruptedException {
        Data data =new Data();
        Thread p2 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {

                    data.increase();
                    Thread.sleep(400);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "p2");
        Thread c1 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrease();
                    Thread.sleep(400);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "c1");
        Thread p1 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.increase();
                    Thread.sleep(400);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "p1");

        Thread c2 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrease();
                    Thread.sleep(400);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "c2");
        p2.start();
        p1.start();
        c1.start();
        c2.start();
        Thread.State sc1 = c1.getState();
        Thread.State sc2 = c2.getState();

        Thread tt = new Thread(()->{
            int i = 0;
            while (true){
                System.out.println(i++);
                try {
                    Thread.sleep(400);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

        });
        tt.setName("partner");
        tt.setDaemon(true);
        tt.start();

//        while (sc1!=Thread.State.TERMINATED || sc2!=Thread.State.TERMINATED){
//            Thread.sleep(500);
//            sc1 = c1.getState();
//            sc2 = c2.getState();
//            System.out.println("c1状态："+sc1+",c2状态："+sc2);
//        }

    }

}

//业务处理
class Data{

    //数字资源
    private int num = 0;

    public int getNum() {
        return num;
    }

    public synchronized void increase() throws InterruptedException {
        //判断等待 不为0时等待消费者

        try{
            while (num!=0){
                this.wait();//指本方法
            }
            num++;

            System.out.println(Thread.currentThread().getName()+"生产数量--"+num);
            Thread.sleep(500);
            //通知
            this.notify();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public synchronized void decrease() throws InterruptedException {
        //判断等待 为0时等待生产
        try{
            while (num==0){
                this.wait();
            }
            num--;
            System.out.println(Thread.currentThread().getName()+"正在消费"+num);
            Thread.sleep(500);
            //通知
            this.notify();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }


}
